/**
 * 
 */
package com.ciukes.dynosgi.jruby;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
import java.util.HashSet;
import java.util.Set;

import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;

import com.ciukes.dynosgi.jruby.ripoff.eclipse.ManifestElement;

class JRubyBundleInitialisator {
	private final JRubyBundleConfig config;
	private final String initScript;
	private final Bundle homeBundle;

	public JRubyBundleInitialisator(Bundle bundle) throws IOException,
			BundleException {
		this.homeBundle = bundle;
		Collection<Bundle> searchInBundles = findSearchInBundles(bundle
				.getBundleContext());
		config = new JRubyBundleConfig(homeBundle, searchInBundles);
		initScript = config.getInitScript();
	}

	private Collection<Bundle> findSearchInBundles(BundleContext bundleContext)
			throws BundleException {
		Collection<Bundle> result = new ArrayList<Bundle>();
		Bundle currentBundle = bundleContext.getBundle();
		result.add(currentBundle);
		addRequiredBundles(result, bundleContext);
		return result;
	}

	@SuppressWarnings("unchecked")
	private void addRequiredBundles(Collection<Bundle> bundleColl,
			BundleContext bundleContext) throws BundleException {
		Bundle currentBundle = bundleContext.getBundle();
		Dictionary<String, String> headers = currentBundle.getHeaders();
		String requiredBundleRaw = headers.get("Require-Bundle");
		ManifestElement[] me = ManifestElement.parseHeader("Require-Bundle",
				requiredBundleRaw);

		Set<String> requiredBundleNames = new HashSet<String>();
		for (ManifestElement manifestElement : me) {
			String bundleName = manifestElement.getValue();
			requiredBundleNames.add(bundleName);
		}

		Bundle[] bundles = bundleContext.getBundles();
		for (Bundle b : bundles) {
			String symbolicName = b.getSymbolicName();
			if (requiredBundleNames.contains(symbolicName)) {
				bundleColl.add(b);
			}
		}
	}

	private boolean shouldInitialise() {
		boolean result;
		result = initScript != null;
		return result;
	}

	public ScriptExecutor initialise() throws InitialisationException {
		ScriptExecutor result = new ScriptExecutor(this.config);
		if (shouldInitialise()) {
			URL script = homeBundle.getEntry(initScript);
			if (script != null) {
				try {
					result.execute(script);
				} catch (ExecutionException e) {
					e.printStackTrace();
					throw new InitialisationException(e);
				}
			}
		}
		return result;
	}
}